package com.pyl.devtools.code;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.baomidou.mybatisplus.enums.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.rules.DbType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.pyl.core.utils.ResultVoUtil;
import com.pyl.core.vo.ResultVo;
import com.pyl.devtools.code.form.Generate;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;

/**
 * @author 灵魂贰婶
 * @date 2019/06/20
 */
@Controller
@RequestMapping("/dev/code")
public class GenerateController {

	@GetMapping
	public String index(Model model) {
		return "/devtools/code/index";
	}

	@PostMapping("/save")
	@ResponseBody
	public ResultVo<?> save(@Validated Generate generate) {
		try {
			String author = generate.getAuthor();
			String location = generate.getLocation();
			String jdbcDriver = generate.getJdbcDriver();
			String jdbcUrl = generate.getJdbcUrl();
			String user = generate.getUser();
			String password = generate.getPassword();
			String basepackage = generate.getBasepackage();
			String[] tables = ArrayUtil.toArray(StrUtil.splitTrim(generate.getTables(), ','), String.class);
			if (ArrayUtil.isEmpty(tables)) {
				return ResultVoUtil.error("数据表不能为空");
			}
			System.out.println(generate.getTables());
			System.out.println(tables);
			// 1.定义全局配置
			GlobalConfig globalConfig = createGlobalConfig(author, location);
			// 2.数据源配置
			DataSourceConfig dataSourceConfig = createDataSourceConfig(jdbcDriver, jdbcUrl, user, password);

			// 3.策略配置 表名
			StrategyConfig strategyConfig = createStrategyConfig(tables);

			// 4.包名策略配置
			PackageConfig packageConfig = createPackageConfig(basepackage + "controller", basepackage + "service",
					basepackage + "service.impl", basepackage + "entity", basepackage + "mapper", "mapper");
			// 5.整合配置
			execute(globalConfig, dataSourceConfig, strategyConfig, packageConfig);
		} catch (Exception e) {
			return ResultVoUtil.error("逆向工程失败");
		}
		return ResultVoUtil.success("逆向工程完成");
	}

	private static void execute(GlobalConfig globalConfig, DataSourceConfig dataSourceConfig, StrategyConfig strategyConfig,
			PackageConfig packageConfig) {
		AutoGenerator autoGenerator = new AutoGenerator();
		autoGenerator.setGlobalConfig(globalConfig).setDataSource(dataSourceConfig).setStrategy(strategyConfig)
				.setPackageInfo(packageConfig).execute();
	}

	/**
	 * 配置包名
	 * 
	 * @param controller
	 * @param service
	 * @param impl
	 * @param entity
	 * @param mapper
	 * @param xml
	 * @return
	 */
	private static PackageConfig createPackageConfig(String controller, String service, String impl, String entity,
			String mapper, String xml) {
		PackageConfig packageConfig = new PackageConfig();

		packageConfig.setParent("").setController(controller).setService(service).setServiceImpl(impl).setEntity(entity)
				.setMapper(mapper).setXml(xml);
		return packageConfig;
	}

	/**
	 * 
	 * @param tables
	 * @return
	 */
	private static StrategyConfig createStrategyConfig(String... tables) {
		StrategyConfig strategyConfig = new StrategyConfig();
		strategyConfig.setCapitalMode(true)// 开启全局大写命名
				.setDbColumnUnderline(true)// 指定表名字段名是否使用下划线
				.setNaming(NamingStrategy.underline_to_camel)// 表字段下划线转驼峰命名
				.setInclude(tables).setEntityLombokModel(true)// 生成lombok模型
				.setEntityBuilderModel(false) // 建造者模式
				.entityTableFieldAnnotationEnable(true);// 每个字段都带有注解
		return strategyConfig;
	}

	/**
	 * 
	 * @param driverName
	 * @param url
	 * @param userName
	 * @param password
	 * @return
	 */
	private static DataSourceConfig createDataSourceConfig(String driverName, String url, String userName,
			String password) {
		DataSourceConfig dataSourceConfig = new DataSourceConfig();
		dataSourceConfig.setDbType(DbType.MYSQL).setUrl(url).setDriverName(driverName).setUsername(userName)
				.setPassword(password);
		return dataSourceConfig;
	}

	/**
	 * 
	 * @param auther
	 * @param outputDir
	 * @return
	 */
	private static GlobalConfig createGlobalConfig(String auther, String outputDir) {
		GlobalConfig globalConfig = new GlobalConfig();
		globalConfig.setActiveRecord(false)// 不适用AR模式
				.setEnableCache(false)// 不使用二级缓存
				.setAuthor(auther)// 设置作者
				.setOutputDir(outputDir)// 设置输出路径
				.setFileOverride(true)// 多次生成是否文件覆盖
				.setIdType(IdType.AUTO)// 数据库id自增
				.setBaseResultMap(true)// 带有baseresultmap
				.setBaseColumnList(true)// 带有基本的sql
				.setServiceName("%sService").setServiceImplName("%sServiceImpl").setMapperName("%sMapper")
				.setXmlName("%sMapper").setControllerName("%sController");
		return globalConfig;
	}
	
	
	public static void main(String[] args) {
		try {
			System.out.println("=======>逆向工程开始");

			String author = "灵魂贰婶";
			String location = "D:/";

			String jdbcDriver = "com.mysql.jdbc.Driver";

			String jdbcUrl = "jdbc:mysql://127.0.0.1:3306/ling?useSSL=false&characterEncoding=utf-8&serverTimezone=GMT%2B8";

			String user = "root";

			String password = "root";

			String basepackage = "com.pyl.shopping.";

			String[] tables = { "bss_buyer","bss_category","bss_commodity","bss_headline","bss_order"};

			// 1.定义全局配置
			GlobalConfig globalConfig = createGlobalConfig(author, location);
			// 2.数据源配置
			DataSourceConfig dataSourceConfig = createDataSourceConfig(jdbcDriver, jdbcUrl, user, password);

			// 3.策略配置 表名
			StrategyConfig strategyConfig = createStrategyConfig(tables);

			// 4.包名策略配置
			PackageConfig packageConfig = createPackageConfig(basepackage + "controller", basepackage + "service",
					basepackage + "service.impl", basepackage + "entity", basepackage + "mapper", "mapper");

			// 5.整合配置
			execute(globalConfig, dataSourceConfig, strategyConfig, packageConfig);

			System.out.println("=======>逆向工程完成");
		} catch (Exception e) {
			System.out.println("=======>逆向工程失败");
			e.printStackTrace();

		}
	}
	
	
	
}
